Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add electrum support #131

Merged
merged 11 commits into from
Feb 26, 2024
Merged

Add electrum support #131

merged 11 commits into from
Feb 26, 2024

Conversation

dr-orlovsky
Copy link
Member

@dr-orlovsky dr-orlovsky commented Feb 13, 2024

These are electrum-specific commits extracted from v0.11 branch #103, including the commit from #126 PR, which I move here to be able to run CI on the whole thing.

We need to make sure this compiles to WASM before merging - and I expect it should due to BP-WG/bp-wallet@9d1cf14, making #127 and #128 outdated.

I will wait for @crisdut and @zoedberg confirmation before merging this and close the other two PRs trying to fix default features of bp-wallet

@zoedberg
Copy link
Contributor

it works good, thanks

@crisdut
Copy link
Member

crisdut commented Feb 13, 2024

I tried compile for wasm target and I receive some errors:

wasm-pack build --no-default-features --features serde

First Error : AnyResolver

error[E0004]: non-exhaustive patterns: type `&AnyResolver` is non-empty
  --> src/resolvers/any.rs:77:15
   |
77 |         match self {
   |               ^^^^
   |
note: `AnyResolver` defined here
  --> src/resolvers/any.rs:34:10
   |
34 | pub enum AnyResolver {
   |          ^^^^^^^^^^^
   = note: the matched value is of type `&AnyResolver`
   = note: references are always considered inhabited
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
   |
77 ~         match self {
78 +             _ => todo!(),
79 +         }
   |

Regards the blocking http calls, both options in AnyResolver does not working in wasm target.

We can work with a "Dummy" option that would be great for doing some tests without accessing external data, for example:

#[derive(From)]
#[non_exhaustive]
pub enum AnyResolver<T> 
where
    T: ResolveWitness + ResolveHeight + std::fmt::Debug,
{
    #[cfg(feature = "electrum")]
    #[from]
    /// Electrum resolver
    Electrum(Box<electrum::Resolver>),
    #[cfg(feature = "esplora_blocking")]
    #[from]
    /// Esplora resolver
    Esplora(Box<esplora_blocking::Resolver>),
    /// Dummy resolver
    Dummy(T),
}

Second Error : cli as default-member

    |
397 |         let len = self.socket.readv([&mut header, buf])?;
    |                               ^^^^^ method not found in `UdpSocket`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
note: `WritevExt` defines an item `readv`, perhaps you need to implement it
   --> /Users/crisdut/.cargo/registry/src/index.crates.io-6f17d22bba15001f/socks-0.3.4/src/writev.rs:4:1
    |
4   | pub trait WritevExt {
    | ^^^^^^^^^^^^^^^^^^^

If we remove "cli" from default-members, in Cargo.toml, the compilation works.

default-members = [
    "psbt",
    "fs",
    "."
]

@cryptoquick
Copy link
Member

cryptoquick commented Feb 13, 2024

@crisdut Notice that you conditionally compile it without either esplora or electrum feature, as you have, the match arms would be empty:

https://github.com/RGB-WG/rgb/pull/131/files#diff-7930ac95a70feec3b3c3ff5c75d402c65de5c29c46f784d9e2bc95da0e5ba3d8R78-R81

Perhaps it would make sense to just mark it as non-exhaustive:
#[non_exhaustive]
See: https://doc.rust-lang.org/beta/reference/attributes/type_system.html#the-non_exhaustive-attribute

@dr-orlovsky
Copy link
Member Author

dr-orlovsky commented Feb 15, 2024

Yeah, that's why I suggested making AnyResolver non-exhaustive here: #126 (comment)

Also, this is the reason I was against this approach: #126 (review)

I do not remember all the reasons, but when we tried it in rust-bitcoin, it was a bag of pain in all downstream dependencies, so I wonder if we should go this route...

@zoedberg
Copy link
Contributor

By running the command that @crisdut is giving (wasm-pack build --no-default-features --features serde) I receive the following:

Error: crate-type must be cdylib to compile to wasm32-unknown-unknown. Add the following to your Cargo.toml file:

[lib]
crate-type = ["cdylib", "rlib"]
Caused by: crate-type must be cdylib to compile to wasm32-unknown-unknown. Add the following to your Cargo.toml file:

[lib]
crate-type = ["cdylib", "rlib"]

By adding the crate-type as suggested I receive the following errors:

error[E0599]: the method `fill` exists for struct `SystemRandom`, but its trait bounds were not satisfied
   --> /home/zoe/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rustls-0.21.10/src/rand.rs:8:10
    |
7   | /     SystemRandom::new()
8   | |         .fill(bytes)
    | |         -^^^^ method cannot be called on `SystemRandom` due to unsatisfied trait bounds
    | |_________|
    | 
    |
   ::: /home/zoe/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ring-0.17.7/src/rand.rs:112:1
    |
112 |   pub struct SystemRandom(());
    |   -----------------------
    |   |
    |   doesn't satisfy `SystemRandom: SecureRandom`
    |   doesn't satisfy `SystemRandom: ring::rand::sealed::SecureRandom`
    |
    = note: the following trait bounds were not satisfied:
            `SystemRandom: ring::rand::sealed::SecureRandom`
            which is required by `SystemRandom: SecureRandom`

error[E0277]: the trait bound `SystemRandom: ring::rand::sealed::SecureRandom` is not satisfied
  --> /home/zoe/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rustls-0.21.10/src/kx.rs:32:86
   |
32 |             ring::agreement::EphemeralPrivateKey::generate(skxg.agreement_algorithm, &rng).ok()?;
   |                                                                                      ^^^^ the trait `ring::rand::sealed::SecureRandom` is not implemented for `SystemRandom`
   |
   = help: the following other types implement trait `ring::rand::sealed::SecureRandom`:
             FixedByteRandom
             FixedSliceRandom<'_>
             FixedSliceSequenceRandom<'_>
   = note: required for `SystemRandom` to implement `SecureRandom`
   = note: required for the cast from `&SystemRandom` to `&dyn SecureRandom`

error[E0277]: the trait bound `SystemRandom: ring::rand::sealed::SecureRandom` is not satisfied
   --> /home/zoe/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rustls-0.21.10/src/sign.rs:196:34
    |
196 |             .sign(self.encoding, &rng, message, &mut sig)
    |                                  ^^^^ the trait `ring::rand::sealed::SecureRandom` is not implemented for `SystemRandom`
    |
    = help: the following other types implement trait `ring::rand::sealed::SecureRandom`:
              FixedByteRandom
              FixedSliceRandom<'_>
              FixedSliceSequenceRandom<'_>
    = note: required for `SystemRandom` to implement `SecureRandom`
    = note: required for the cast from `&SystemRandom` to `&dyn SecureRandom`

error[E0277]: the trait bound `SystemRandom: ring::rand::sealed::SecureRandom` is not satisfied
   --> /home/zoe/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rustls-0.21.10/src/sign.rs:232:50
    |
232 |         EcdsaKeyPair::from_pkcs8(sigalg, &der.0, &rng)
    |                                                  ^^^^ the trait `ring::rand::sealed::SecureRandom` is not implemented for `SystemRandom`
    |
    = help: the following other types implement trait `ring::rand::sealed::SecureRandom`:
              FixedByteRandom
              FixedSliceRandom<'_>
              FixedSliceSequenceRandom<'_>
    = note: required for `SystemRandom` to implement `SecureRandom`
    = note: required for the cast from `&SystemRandom` to `&dyn SecureRandom`

error[E0277]: the trait bound `SystemRandom: ring::rand::sealed::SecureRandom` is not satisfied
   --> /home/zoe/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rustls-0.21.10/src/sign.rs:234:78
    |
234 |             .or_else(|_| Self::convert_sec1_to_pkcs8(scheme, sigalg, &der.0, &rng))
    |                                                                              ^^^^ the trait `ring::rand::sealed::SecureRandom` is not implemented for `SystemRandom`
    |
    = help: the following other types implement trait `ring::rand::sealed::SecureRandom`:
              FixedByteRandom
              FixedSliceRandom<'_>
              FixedSliceSequenceRandom<'_>
    = note: required for `SystemRandom` to implement `SecureRandom`
    = note: required for the cast from `&SystemRandom` to `&dyn SecureRandom`

error[E0277]: the trait bound `SystemRandom: ring::rand::sealed::SecureRandom` is not satisfied
   --> /home/zoe/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rustls-0.21.10/src/sign.rs:317:19
    |
317 |             .sign(&rng, message)
    |                   ^^^^ the trait `ring::rand::sealed::SecureRandom` is not implemented for `SystemRandom`
    |
    = help: the following other types implement trait `ring::rand::sealed::SecureRandom`:
              FixedByteRandom
              FixedSliceRandom<'_>
              FixedSliceSequenceRandom<'_>
    = note: required for `SystemRandom` to implement `SecureRandom`
    = note: required for the cast from `&SystemRandom` to `&dyn SecureRandom`

so maybe to build on wasm we need to patch some dependencies differently?

Anyway, when implementing the AnyResolver I was not considering that someone could need building the library with nor electrum nor esplora features. The fix for this should be simple, just protect the any module and the AnyResolver like so:

#[cfg(feature = "electrum")]
#[cfg(feature = "esplora_blocking")]
mod any;

#[cfg(feature = "electrum")]
#[cfg(feature = "esplora_blocking")]
pub use any::AnyResolver;

@cryptoquick
Copy link
Member

cryptoquick commented Feb 15, 2024

I think I figured out what was keeping this from compiling to WASM. See #132

@@ -66,13 +68,15 @@ name = "rgb_rt"
[dependencies]
amplify = { workspace = true }
baid58 = { workspace = true }
bitcoin = { workspace = true, optional = true }
commit_verify = { workspace = true }
strict_types = { workspace = true }
bp-core = { workspace = true }
bp-std = { workspace = true }
bp-wallet = { workspace = true, features = ["fs"] }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @zoedberg,

Please set default-features=false, to avoid load bp-esplora blocking client along wasm compilation.

Suggested change
bp-wallet = { workspace = true, features = ["fs"] }
bp-wallet = { workspace = true, default-features = false, features = ["fs"] }

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @crisdut, sorry for the late answer but I've somehow missed this. Thanks for the tip, unfortunately though I'm still receiving the previously reported errors.

@zoedberg
Copy link
Contributor

I think I figured out what was keeping this from compiling to WASM. See #132

Nice, so it seems #132, which is using my suggested fix, has fixed the wasm compilation (I've tried the branch and I can confirm it). So @dr-orlovsky, can we merge that PR into this and then this PR into master?

@dr-orlovsky dr-orlovsky merged commit 87ff1bb into master Feb 26, 2024
13 of 20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Feature request
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

4 participants